diff --git a/src/iconview/qiconview.cpp b/src/iconview/qiconview.cpp
index c1ea8cc..36b5da2 100644
--- a/src/iconview/qiconview.cpp
+++ b/src/iconview/qiconview.cpp
@@ -214,6 +214,7 @@ public:
     QIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem,
 	*startDragItem, *pressedItem, *selectAnchor, *renamingItem;
     QRect *rubber;
+    QPixmap *backBuffer;
     QTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer,
 	*fullRedrawTimer;
     int rastX, rastY, spacing;
@@ -2789,6 +2790,7 @@ QIconView::QIconView( QWidget *parent, const char *name, WFlags f )
     d->currentItem = 0;
     d->highlightedItem = 0;
     d->rubber = 0;
+    d->backBuffer = 0;
     d->scrollTimer = 0;
     d->startDragItem = 0;
     d->tmpCurrentItem = 0;
@@ -2942,6 +2944,8 @@ QIconView::~QIconView()
 	delete item;
 	item = tmp;
     }
+    delete d->backBuffer;
+    d->backBuffer = 0;
     delete d->fm;
     d->fm = 0;
 #ifndef QT_NO_TOOLTIP
@@ -4943,6 +4947,47 @@ void QIconView::contentsDropEvent( QDropEvent *e )
 #endif
 
 /*!
+    This function grabs all paintevents that otherwise would have been
+    processed by the QScrollView::viewportPaintEvent(). Here we use a
+    doublebuffer to reduce 'on-paint' flickering on QIconView
+    (and of course its children).
+    
+    \sa QScrollView::viewportPaintEvent(), QIconView::drawContents()
+*/
+
+void QIconView::bufferedPaintEvent( QPaintEvent* pe )
+{
+    QWidget* vp = viewport();
+    QRect r = pe->rect() & vp->rect();
+    int ex = r.x() + contentsX();
+    int ey = r.y() + contentsY();
+    int ew = r.width();
+    int eh = r.height();
+
+    if ( !d->backBuffer )
+	d->backBuffer = new QPixmap(vp->size());
+    if ( d->backBuffer->size() != vp->size() ) {
+	// Resize function (with hysteresis). Uses a good compromise between memory
+	// consumption and speed (number) of resizes.
+	float newWidth = (float)vp->width();
+	float newHeight = (float)vp->height();
+	if ( newWidth > d->backBuffer->width() || newHeight > d->backBuffer->height() )
+	{
+	    newWidth *= 1.1892;
+	    newHeight *= 1.1892;
+	    d->backBuffer->resize( (int)newWidth, (int)newHeight );
+	} else if ( 1.5*newWidth < d->backBuffer->width() || 1.5*newHeight < d->backBuffer->height() )
+	    d->backBuffer->resize( (int)newWidth, (int)newHeight );
+    }
+
+    QPainter p;
+    p.begin(d->backBuffer, vp);
+    drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh);
+    p.end();
+    bitBlt(vp, r.x(), r.y(), d->backBuffer, r.x(), r.y(), ew, eh);
+}
+
+/*!
     \reimp
 */
 
@@ -5726,7 +5771,7 @@ bool QIconView::eventFilter( QObject * o, QEvent * e )
 		    if ( !d->rubber )
 			drawDragShapes( d->oldDragPos );
 		}
-		viewportPaintEvent( (QPaintEvent*)e );
+		bufferedPaintEvent( (QPaintEvent*)e );
 		if ( d->dragging ) {
 		    if ( !d->rubber )
 			drawDragShapes( d->oldDragPos );
diff --git a/src/iconview/qiconview.h b/src/iconview/qiconview.h
index 97780d8..109779f 100644
--- a/src/iconview/qiconview.h
+++ b/src/iconview/qiconview.h
@@ -452,6 +452,7 @@ protected:
     void contentsDropEvent( QDropEvent *e );
 #endif
 
+    void bufferedPaintEvent( QPaintEvent* );
     void resizeEvent( QResizeEvent* e );
     void keyPressEvent( QKeyEvent *e );
     void focusInEvent( QFocusEvent *e );
